﻿namespace MicroCloud.Entity
{
    #region "数据上下文接口"
    /// <summary>
    /// 数据上下文接口
    /// </summary>
    public interface IDbContext
    {
        #region "方法"
        #region "提交数据上下文的变更"
        /// <summary>
        /// 提交数据上下文的变更
        /// </summary>
        /// <returns>操作影响的记录数</returns>
        int SaveChanges();
        #endregion
        #region "异步方式提交数据上下文的所有变更"
        /// <summary>
        /// 异步方式提交数据上下文的所有变更
        /// </summary>
        /// <param name="cancelToken">任务取消标识</param>
        /// <returns>操作影响的行数</returns>
        Task<int> SaveChangesAsync(CancellationToken cancelToken = default(CancellationToken));
        #endregion

        #region "开启或使用现有事务"
        /// <summary>
        /// 开启或使用现有事务
        /// </summary>
        /// <param name="isolationLevel">事务隔离级别</param>
        void BeginOrUseTransaction(IsolationLevel? isolationLevel = null);
        #endregion

        #region "异步开启或使用现有事务"
        /// <summary>
        /// 异步开启或使用现有事务
        /// </summary>
        /// <param name="isolationLevel">事务隔离级别</param>
        /// <param name="cancellationToken">任务取消标识</param>
        /// <returns></returns>
        Task BeginOrUseTransactionAsync(IsolationLevel? isolationLevel = null, CancellationToken cancellationToken = default);
        #endregion

        #region "是否已启用事务"
        /// <summary>
        /// 是否已启用事务
        /// </summary>
        /// <returns></returns>
        bool IsEnableTransaction();
        #endregion

        #region "获取实体数据表默认架构"
        /// <summary>
        /// 获取实体数据表默认架构
        /// </summary>
        /// <param name="entityType">实体类型</param>
        /// <returns>映射的数据表架构</returns>
        string GetTableDefaultSchema(Type entityType);
        #endregion
        #region "获取实体数据表架构"
        /// <summary>
        /// 获取实体数据表架构
        /// </summary>
        /// <param name="entityType">实体类型</param>
        /// <returns>映射的数据表架构</returns>
        string GetTableSchema(Type entityType);
        #endregion
        #region "获取实体数据表名称"
        /// <summary>
        /// 获取实体数据表名称
        /// </summary>
        /// <param name="entityType">实体类型</param>
        /// <returns>映射的数据表名称</returns>
        string GetTableName(Type entityType);
        #endregion
        #region "获取实体数据列数组"
        /// <summary>
        /// 获取实体数据列数组
        /// </summary>
        /// <param name="entityType">实体类型</param>
        /// <returns></returns>
        IDictionary<string, string> GetTableColumns(Type entityType);
        #endregion
        #region "获取实体主键列数组"
        /// <summary>
        /// 获取实体主键列数组
        /// </summary>
        /// <param name="entityType">实体类型</param>
        /// <returns></returns>
        IDictionary<string, string> GetTablePrimaryKeyColumns(Type entityType);
        #endregion

        #region "获取实体数据视图默认架构"
        /// <summary>
        /// 获取实体数据视图默认架构
        /// </summary>
        /// <param name="entityType">实体类型</param>
        /// <returns>映射的数据视图架构</returns>
        string GetDefaultViewSchema(Type entityType);
        #endregion
        #region "获取实体数据视图架构"
        /// <summary>
        /// 获取实体数据视图架构
        /// </summary>
        /// <param name="entityType">实体类型</param>
        /// <returns>映射的数据视图架构</returns>
        string GetViewSchema(Type entityType);
        #endregion
        #region "获取实体数据视图名称"
        /// <summary>
        /// 获取实体数据视图名称
        /// </summary>
        /// <param name="entityType">实体类型</param>
        /// <returns>映射的数据视图名称</returns>
        string GetViewName(Type entityType);
        #endregion

        #region "是否是关系型数据库"
        /// <summary>
        /// 是否是关系型数据库
        /// </summary>
        /// <returns></returns>
        bool IsRelationalTransaction();
        #endregion
        #region "关系型数据库是否存在"
        /// <summary>
        /// 关系型数据库是否存在
        /// </summary>
        /// <returns></returns>
        bool ExistsRelationalDatabase();
        #endregion

        #region "获取数据上下文配置选项"
        /// <summary>
        /// 获取数据上下文配置选项
        /// </summary>
        /// <returns>数据上下文配置选项</returns>
        DbContextOption GetOptions();
        #endregion
        #region "获取数据库类型"
        /// <summary>
        /// 获取数据库类型
        /// </summary>
        /// <returns>数据库类型枚举</returns>
        DatabaseType GetDatabaseType();
        #endregion
        #region "获取数据库连接字符串"
        /// <summary>
        /// 获取数据库连接字符串
        /// </summary>
        /// <returns>数据库连接字符串</returns>
        string GetConnectionString();
        #endregion

        #region "基于原始SQL查询创建LINQ查询，该查询返回数据库提供程序本机支持的标量类型的结果集。"
        /// <summary>
        /// 基于原始SQL查询创建LINQ查询，该查询返回数据库提供程序本机支持的标量类型的结果集。
        /// </summary>
        /// <param name="sql">带参数的SQL查询的插值字符串</param>
        /// <returns>受影响的行数</returns>
        IQueryable<TResult> SqlQuery<TResult>(FormattableString sql);
        #endregion
        #region "基于原始SQL查询创建LINQ查询，该查询返回数据库提供程序本机支持的标量类型的结果集。"
        /// <summary>
        /// 基于原始SQL查询创建LINQ查询，该查询返回数据库提供程序本机支持的标量类型的结果集。
        /// </summary>
        /// <param name="sql">要执行的SQL</param>
        /// <param name="parameters">要与SQL一起使用的参数</param>
        /// <returns>受影响的行数</returns>
        IQueryable<TResult> SqlQueryRaw<TResult>(string sql, params object[] parameters);
        #endregion
        #region "执行Sql"
        /// <summary>
        /// 执行Sql
        /// </summary>
        /// <param name="sql">带参数的SQL查询的插值字符串</param>
        /// <returns>受影响的行数</returns>
        int ExecuteSql(FormattableString sql);
        #endregion
        #region "异步执行Sql"
        /// <summary>
        /// 异步执行Sql
        /// </summary>
        /// <param name="sql">要执行的SQL</param>
        /// <returns>受影响的行数</returns>
        Task<int> ExecuteSqlAsync(FormattableString sql);
        #endregion
        #region "执行指定的Sql语句"
        /// <summary>
        /// 执行指定的Sql语句
        /// </summary>
        /// <param name="sql">要执行的SQL</param>
        /// <param name="parameters">要与SQL一起使用的参数</param>
        /// <returns>受影响的行数</returns>
        int ExecuteSqlRaw(string sql, params object[] parameters);
        #endregion
        #region "异步执行指定的Sql语句"
        /// <summary>
        /// 异步执行指定的Sql语句
        /// </summary>
        /// <param name="sql">要执行的SQL</param>
        /// <param name="parameters">要与SQL一起使用的参数</param>
        /// <returns>受影响的行数</returns>
        Task<int> ExecuteSqlRawAsync(string sql, params object[] parameters);
        #endregion
        #region "执行指定的格式化Sql语句"
        /// <summary>
        /// 执行指定的格式化Sql语句
        /// </summary>
        /// <param name="sql">带有参数的SQL查询的插值字符串</param>
        /// <returns>受影响的行数</returns>
        int ExecuteSqlInterpolated(FormattableString sql);
        #endregion
        #region "异步执行指定的格式化Sql语句"
        /// <summary>
        /// 异步执行指定的格式化Sql语句
        /// </summary>
        /// <param name="sql">带有参数的SQL查询的插值字符串</param>
        /// <returns>受影响的行数</returns>
        Task<int> ExecuteSqlInterpolatedAsync(FormattableString sql);
        #endregion

        #region "执行指定的Sql语句并返回DataSet数据"
        /// <summary>
        /// 执行指定的Sql语句并返回DataTable数据
        /// </summary>
        /// <param name="sql">要执行的SQL</param>
        /// <param name="parameters">要与SQL一起使用的参数</param>
        /// <returns>DataSet数据</returns>
        DataSet SqlQueryToDataSet(string sql, params object[] parameters);
        #endregion
        #region "异步执行指定的Sql语句并返回DataSet数据"
        /// <summary>
        /// 异步执行指定的Sql语句并返回DataSet数据
        /// </summary>
        /// <param name="sql">要执行的SQL</param>
        /// <param name="parameters">要与SQL一起使用的参数</param>
        /// <returns>DataSet数据</returns>
        Task<DataSet> SqlQueryToDataSetAsync(string sql, params object[] parameters);
        #endregion

        #region "执行指定的Sql语句并返回DataTable数据"
        /// <summary>
        /// 执行指定的Sql语句并返回DataTable数据
        /// </summary>
        /// <param name="sql">要执行的SQL</param>
        /// <param name="parameters">要与SQL一起使用的参数</param>
        /// <returns>DataTable数据</returns>
        DataTable SqlQueryToDataTable(string sql, params object[] parameters);
        #endregion
        #region "异步执行指定的Sql语句并返回DataTable数据"
        /// <summary>
        /// 异步执行指定的Sql语句并返回DataTable数据
        /// </summary>
        /// <param name="sql">要执行的SQL</param>
        /// <param name="parameters">要与SQL一起使用的参数</param>
        /// <returns>DataTable数据</returns>
        Task<DataTable> SqlQueryToDataTableAsync(string sql, params object[] parameters);
        #endregion

        #region "执行指定的Sql语句并返回指定类型数据"
        /// <summary>
        /// 执行指定的Sql语句并返回指定类型数据
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="sql">要执行的SQL</param>
        /// <param name="parameters">要与SQL一起使用的参数</param>
        /// <returns>指定类型数据集合</returns>
        List<T> SqlQueryToModel<T>(string sql, params object[] parameters) where T : class, new();
        #endregion
        #region "异步执行指定的Sql语句并返回指定类型数据"
        /// <summary>
        /// 异步执行指定的Sql语句并返回指定类型数据
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="sql">要执行的SQL</param>
        /// <param name="parameters">要与SQL一起使用的参数</param>
        /// <returns>指定类型数据集合</returns>
        Task<List<T>> SqlQueryToModelAsync<T>(string sql, params object[] parameters) where T : class, new();
        #endregion

        #region "获取数据库连接"
        /// <summary>
        /// 获取数据库连接
        /// </summary>
        /// <returns>数据库连接对象</returns>
        DbConnection GetDbConnection();
        #endregion
        #region "创建数据库命令"
        /// <summary>
        /// 创建数据库命令
        /// </summary>
        /// <param name="dbConnection">数据库连接对象</param>
        /// <returns>数据库命令对象</returns>
        DbCommand CreateDbCommand(out DbConnection dbConnection);
        #endregion

        #endregion

    }
    #endregion

}
